﻿#define _CRT_SECURE_NO_WARNINGS
//#include <stdio.h>
//{
//	int arr[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
//	      //该下标为0，1，2，3，4，5，6，7，8，9
//	printf("%d", arr[9]);
//	return 0;
//#include <stdio.h>
//void bubble_sort(int arr[])
//{
//	int i = 0;
//	int sz = sizeof(arr) / sizeof(arr[0]);
//
//	//冒泡排序的趟数
//	for (i = 0; i < sz - 1; i++)
//	{
//		//一趟冒泡排序的过程
//		int j = 0;
//		for (j = 0; j < sz - 1 - i; j++)
//		{
//			if (arr[j] > arr[j + 1])
//			{
//				int tmp = arr[j];
//				arr[j] = arr[j + 1];
//				arr[j + 1] = tmp;
//			}
//		}
//	}
//}
//int main()
//{
//	int arr[] = { 3,1,5,9,2,4,7,6,8,0 };
//	//排序 - 升序
//	//冒泡排序
//
//	bubble_sort(arr);//arr是数组首元素的地址
//
//	int i = 0;
//	for (i = 0; i < 10; i++)
//	{
//		printf("%d ", arr[i]);
//	}
//
//	return 0;
//}
//int main()
//{
//	int arr[10] = { 0 };
//	printf("%p\n", arr);
//	printf("%p\n", arr+1);
//
//	printf("%p\n", &arr[0]);
//	printf("%p\n", &arr[0]+1);
//
//	printf("%p\n", &arr);
//	printf("%p\n", &arr+1);
//
//
//	//printf("%d\n", sizeof(arr));//40
//	return 0;
//}
#include <stdio.h>

//int main()
//{
//	  / 除法 - 得到的是商
//	 除法操作符的两个操作数都是整数的话，执行的是整数除法
//	 除法操作符的两个操作数只要有一个浮点数，执行的是小数除法
//	 
//	  % 取模（	取余）得到的是余数
//	  取模操作符的操作数必须是整数
//
//	printf("%lf\n", 10 / 3.0);//5
//	printf("%d\n", 10 % 2);//0
//	return 0;
//}
//>> 右移操作符
//VS：算术右移
//int main()
//{
//	int a = -5;
//	//10000000000000000000000000000101
//	//11111111111111111111111111111010
//	//11111111111111111111111111111011
//	//
//	int b = a >> 1;
// 
//	//11111111111111111111111111111101
//	//11111111111111111111111111111100
//	//10000000000000000000000000000011
//	//-3
//	printf("b = %d\n", b);
//	printf("a = %d\n", a);//-5
//
//	return 0;
//}#include <stdio.h>
#include <stdio.h>
//int main()
//{
//	int arr[10] = { 0 };
//	int* p = arr;
//	int i = 0;
//	for (i = 0; i <= 11; i++)
//	{
//		//当指针指向的范围超出数组arr的范围时，p就是野指针
//		*(p++) = i;
//	}
//	return 0;
//struct S
//{
//	int arr[100];
//	int n;
//};
//
//void print1(struct S ss)
//{
//	int i = 0;
//	for (i = 0; i < 10; i++)
//	{
//		printf("%d ", ss.arr[i]);
//	}
//	printf("\n%d\n", ss.n);
//}
//
//void print2(struct S* ps)
//{
//	int i = 0;
//	for (i = 0; i < 10; i++)
//	{
//		printf("%d ", ps->arr[i]);
//	}
//	printf("\n%d\n", ps->n);
//}
//
//int main()
//{
//	struct S s = { {1,2,3,4,5}, 100 };
//	print1(s);
//	print2(&s);
//
//	return 0;
//}
//#include <stdio.h>
//int main()
//{
//	int i = 0;
//	int arr[10] = { 0 };
//	for (i = 0; i <= 12; i++)
//	{
//		arr[i] = 0;
//		printf("hehe\n");
//	}
//	return 0;
//}
//strcpy函数返回的是目标空间的起始地址

//char* my_strcpy(char* dest, const char* src)
//{
//	//断言 - 保证指针的有效性
//	assert(dest && src);
//	char* ret = dest;
//	//把src指向的字符串拷贝到dest指向是的数组空间，包括\0字符
//	while (*dest++ = *src++)
//	{
//		;
//	}
//	return ret;
//}
//模拟实现库函数：strcpy
//strcpy
// string copy
//字符串拷贝
//#include <string.h>
//int main()
//{
//	//int n = 10;
//	//n = 20;
//	int n = 100;
//	const int m = 0;
//	//m = 20;//err
//	//const 修饰指针
//	//1. const 放在*的左边, *p不能改了，也就是p指向的内容，不能通过p来改变了。但是p是可以改变的，p可以指向其他的变量
//	//2. const 放在*的右边,限制的是p，p不能改变，但是p指向的内容*p，是可以通过p来改变的
//	//
//	//const int * p = &m;
//	//*p = 20;//err
//	//p = &n;//ok
//
//	int* const p = &m;
//	*p = 20;//ok
//	p = &n;//err
//	printf("%d\n", m);
//
//	return 0;
//}
#include <string.h>
//整数的二进制表示形式：
//原码
//反码
//补码
//
//int main()
//{
//	int a = 1;
//	char*p = (char*)&a;//int*
//	if (*p == 1)
//		printf("小端\n");
//	else
//		printf("大端\n");
//
//	return 0;
//}

//如果是大端返回0
//如果是小端返回1
//int check_sys()//方案1
//{
//	int a = 1;
//	char* p = (char*)&a;//int*
//	if (*p == 1)
//		return 1;//小端
//	else
//		return 0;//大端
//}
//
//int check_sys()//进一步优化
//{
//	int a = 1;
//	if (*(char*)&a == 1)
//		return 1;//小端
//	else
//		return 0;//大端
//}
//
//int check_sys()//还可以继续优化
//{
//	int a = 1;
//	return *(char*)&a;
//}
//
//int main()
//{
//	if (check_sys() == 1)
//		printf("小端\n");
//	else
//		printf("大端\n");
//	return 0;
//}
// 2.
//#include <stdio.h>
//int main()
//{
//	char a = 128;
//	//1000000000000000000000010000000原码
//	//1111111111111111111111101111111反码
//	//1111111111111111111111110000000补码
//	//10000000 - a截断
//	// 整型提升
//	//1111111111111111111111110000000
//	printf("%u\n", a);
//	//所以结果为：4294967168
//	return 0;
//}
//#include <stdio.h>
//
//int main()
//{
//	int i = -20;
	////unsigned int j = 10;
	//10000000 00000000 00000000 00010100
	//11111111 11111111 11111111 11101011
	//11111111 11111111 11111111 11101100 - 补码
	//00000000 00000000 00000000 00001010 - 原码
	//11111111 11111111 11111111 11110110 - 计算机的结果，是存在内存中，是补码
	//11111111 11111111 11111111 11110101
	//10000000 00000000 00000000 00001010
	//-10
//#include <stdio.h>
//int main()
//{
//	char str1[] = "hello bit.";
//	char str2[] = "hello bit.";
//
//	const char* str3 = "hello bit.";
//	const char* str4 = "hello bit.";
//
//	if (str1 == str2)
//		printf("str1 and str2 are same\n");
//	else
//		printf("str1 and str2 are not same\n");
//
//	if (str3 == str4)
//		printf("str3 and str4 are same\n");
//	else
//		printf("str3 and str4 are not same\n");
//
//	return 0;
//}
//int main()
//{
//	char* arr[] = { "abcdef", "hehe", "qwer" };
//	int i = 0;
//	for (i = 0; i < 3; i++)
//	{
//		printf("%s\n", arr[i]);
//	}
//	return 0;
//}
//int main()
//{
//	int arr1[] = { 1,2,3,4,5 };
//	int arr2[] = { 2,3,4,5,6 };
//	int arr3[] = { 3,4,5,6,7 };
//
//	arr[i] == *(arr+i)
//	arr是一个存放整型指针的数组
//	int* arr[] = { arr1, arr2, arr3 };
//	int i = 0;
//	for (i = 0; i < 3; i++)
//	{
//		int j = 0;
//		for (j = 0; j < 5; j++)
//		{
//			printf("%d ", arr[i][j]);
//			printf("%d ", *(arr[i]+j));
//		}
//		printf("\n");
//	}
//	return 0;
//}
//数组名绝大部分情况下是数组首元素的地址
//但是有2个例外：
//1. sizeof(数组名) - sizeof内部单独放一个数组名的时候，数组名表示的整个数组，计算得到的是数组的总大小
//2. &arr  - 这里的数组名表示整个数组，取出的是整个数组的地址,从地址值的角度来讲和数组首元素的地址是一样的，但是意义不一样
//

//void print1(int arr[3][5], int r, int c)
//{
//	int i = 0;
//	for (i = 0; i < 3; i++)
//	{
//		int j = 0;
//		for (j = 0; j < 5; j++)
//		{
//			printf("%d ", arr[i][j]);
//		}
//		printf("\n");
//	}
//}
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
typedef struct st_type

{
	int i;
	int a[];//柔性数组成员

}type_a;

//柔性数组
//
//struct S
//{
//	int n;
//	char c;
//	int arr[];//柔性数组成员
//};

//1. 结构中的柔性数组成员前面必须至少一个其他成员。
struct S
{
	int arr[];//柔性数组成员
};
//这种写法err
//2. sizeof 返回的这种结构大小不包括柔性数组的内存。
struct S
{
	int n;//4
	char c;//1  但要考虑对齐
	int arr[];//柔性数组成员
};
int main()
{

	printf("%d\n", sizeof(struct S));//代码结果打印是8

	return 0;
}
//3. 包含柔性数组成员的结构用malloc ()函数进行内存的动态分配，
//并且分配的内存应该大于结构的大小，以适应柔性数组的预期大小。
#include <string.h>
#include <errno.h>
#include <stdlib.h>

struct S
{
	int n;
	char c;
	int arr[0];//柔性数组成员
};

int main()
{
	//      8               + 40
	struct S* ps = (struct S*)malloc(sizeof(struct S) + 10*sizeof(int));
	if (ps == NULL)
	{
		printf("%s\n", strerror(errno));
		return 1;
	}
	//使用
	ps->n = 100;
	ps->c = 'w';
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		ps->arr[i] = i;
	}
	for (i = 0; i < 10; i++)
	{
		printf("%d\n", ps->arr[i]);
	}
	//调整arr数组的大小
	struct S* ptr = (struct S*)realloc(ps, sizeof(struct S) + 20 * sizeof(int));
	if (ptr == NULL)
	{
		printf("%s\n", strerror(errno));
		return 1;
	}
	else
	{
		ps = ptr;
	}
	//使用
	//...
	
	//释放
	free(ps);
	ps = NULL;

	
	return 0;
}
typedef struct st_type



{
	int i;

	int* p_a;


}type_a;

type_a* p = (type_a*)mal loc(sizeof(type_a));


p->i = 100;


p->p_a = (int*)malloc(p->i * sizeof(int));

//业务处理


for (i = 0; i < 100; i++)
{
	p->p_a[i] = i;
}


//释放空间


free(p->p_a);

p->p_a = NULL;

free(p);

p = NULL;
